#include "ModelMgr.h"

ModelMgr::ModelMgr()
{
	report = new Report();
}

Report * ModelMgr::getReport()
{
	return report;
}
Model * ModelMgr::newModel(int _cantTextures, int _cantAnimations, Animation *_animations, Texture *_textures,string _name)
{
	////////Animations Map////////////////////////////
	Animation * newAnimations;
	Texture * newTextures = new Texture[_cantTextures];
	bool noErrors = true;
	try
	{
		if(_cantAnimations<=0)
		{
			noErrors = false;
			throw noAnimationException;
		}
		if(_cantTextures<=0)
		{
			noErrors = false;
			throw noTextureException;
		}
		if(noErrors)
		{
			itMapaAnimation itAnimationBegin = mapaModelsAnimations.begin();
			itMapaAnimation itAnimationEnd = mapaModelsAnimations.end();

			newAnimations = new Animation[_cantAnimations];
			for(int i=0;i<_cantAnimations;i++)
			{
				bool found = false;
				for(itMapaAnimation it= itAnimationBegin;it!=itAnimationEnd;it++)
				{
					string name = it->first;
					if(name==_animations[i].getAnimation())
					{
						found = true;
						pair<Animation *,int> pairAnimationCont = it->second;
						newAnimations = pairAnimationCont.first;
						pairAnimationCont.second++;
						it->second = pairAnimationCont;
					}
				}
				if(!found)
				{
					newAnimations[i].setAnimation(_animations[i].getAnimation());
					report->cantAnimations++;
					pair<Animation *,int> pairAnimationCont;
					pairAnimationCont.first = &newAnimations[i];
					pairAnimationCont.second = 1;
					mapaModelsAnimations[_animations[i].getAnimation()] = pairAnimationCont; 
				}
			}
			//////Textures Map///////////////////////////////////////
			itMapaTextures itTexturesBegin = mapaModelsTextures.begin();
			itMapaTextures itTexturesEnd = mapaModelsTextures.end();

			newTextures = new Texture[_cantTextures];
			for(int i=0;i<_cantTextures;i++)
			{
				bool found = false;
				for(itMapaTextures it= itTexturesBegin;it!=itTexturesEnd;it++)
				{
					string name = it->first;
					if(name==_textures[i].getTexture())
					{
						found = true;
						pair<Texture *,int> pairTextureCont = it->second;
						newTextures = pairTextureCont.first;
						pairTextureCont.second++;
						it->second = pairTextureCont;
					}
				}
				if(!found)
				{
					newTextures[i].setTexture(_textures[i].getTexture());
					report->cantTextures++;
					pair<Texture *,int> pairTextureCont;
					pairTextureCont.first = &newTextures[i];
					pairTextureCont.second = 1;
					mapaModelsTextures[_textures[i].getTexture()] = pairTextureCont; 
				}
			}
			report->cantModels++;
		}
	}
	catch(NoAnimationException nae)
	{
		std::cout<<nae.getMessage()<<std::endl;
		newAnimations = new Animation[1];
		newTextures = new Texture[1];
	}
	catch(NoTextureException nte)
	{
		std::cout<<nte.getMessage()<<std::endl;
		newAnimations = new Animation[1];
		newTextures = new Texture[1];
	}
	return new Model(_cantTextures,_cantAnimations,newAnimations,newTextures,_name);
}

void ModelMgr::deleteModel(Model *_model)
{
	itMapaAnimation itAnimationBegin = mapaModelsAnimations.begin();
	itMapaAnimation itAnimationEnd = mapaModelsAnimations.end();
	
	Animation * modelAnimations = _model->getAnimation();
	for(int i=0;i<_model->getCantAnimations();i++)
	{
		for(itMapaAnimation it = itAnimationBegin; it != itAnimationEnd; it++)
		{
			string name = it->first;

			if(name==modelAnimations[i].getAnimation())
			{
				pair<Animation *,int> pairAnimationCont = it->second;
				int cont = it->second.second;
				if(cont==1)
				{
					if(pairAnimationCont.first)
					{
						delete(pairAnimationCont.first);
						pairAnimationCont.first=NULL;
						report->cantAnimations--;
					}
					mapaModelsAnimations.erase(it);
					break;
				}
				else
				{
					it->second.second--;
				}
			}
		}
	}

	///////////////Delete Textures//////////////////////////////////
	itMapaTextures itTexturesBegin = mapaModelsTextures.begin();
	itMapaTextures itTexturesEnd = mapaModelsTextures.end();
	
	Texture * modelTextures = _model->getTextures();
	for(int i=0;i<_model->getCantTextures();i++)
	{
		for(itMapaTextures it = itTexturesBegin; it != itTexturesEnd; it++)
		{
			string name = it->first;

			if(name==modelTextures[i].getTexture())
			{
				pair<Texture *,int> pairTextureCont = it->second;
				int cont = it->second.second;
				if(cont==1)
				{
					if(pairTextureCont.first)
					{
						delete(pairTextureCont.first);
						pairTextureCont.first=NULL;
						report->cantTextures--;
					}
					mapaModelsTextures.erase(it);
					break;
				}
				else
				{
					it->second.second--;
				}
			}
		}
	}
	
	/////////////Delete Model/////////////////////////////////////
	report->cantModels--;
	if(_model)
	{
		delete _model;
		_model=NULL;
	}
}